package cl.tinet.trainee.salas.web.mb;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import org.primefaces.context.RequestContext;

import cl.tinet.trainee.salas.ejb.reserva.ReservaSalaInterfaz;
import cl.tinet.trainee.salas.model.ReservaSala;
import cl.tinet.trainee.salas.model.Sala;
import cl.tinet.trainee.salas.model.Segmentos;
import cl.tinet.trainee.salas.model.Usuario;
import cl.tinet.trainee.salas.model.excepciones.NoExisteReserva;

/**
 * 
 * Reservas managed bean.
 * 
 * @author Naht-Sams
 */
@ManagedBean(name = "ReservaMB")
@SessionScoped
public class ReservaMB {
    /**
     * Objeto usuario.
     */
    private Usuario usuario;
    /**
     * Objeto Sala.
     */
    private Sala sala;
    /**
     * Propiedad del MB tipo Sala.
     */
    @ManagedProperty(value = "#{SalaMB}")
    private SalaMB salaMB;
    /**
     * Propiedad del MB tipo Usuario.
     */
    @ManagedProperty(value = "#{UsuarioMB}")
    private UsuarioMB usuarioMB;
    /**
     * Objeto ReservaSala.
     */
    private ReservaSala reservaSala;
    /**
     * Lista de los bloques horarios de la tabla referencial.
     */
    private List<Segmentos> segmentos;
    /**
     * Listado de la buscqueda de reservas.
     */
    private List<ReservaSala> listaReservas;
    /**
     * Atributo temporal Bloque Inicial(hora).
     */
    private String segmentoInicial;
    /**
     * Atributo temporal Bloque Final(hora).
     */
    private String segmentoTermino;
    /**
     * Bean usuario.
     */
    @EJB(mappedName = "ReservaSalaBean", name = "ReservaSalaBean")
    private transient ReservaSalaInterfaz bean;
    /**
     * Fecha seleccionada por el usuario.
     */
    private Date fechaSeleccionada;

    @PostConstruct
    public void init() {
        reservaSala = new ReservaSala();
    }

    public String redireccionarBuscar() {
        this.usuario = new Usuario();
        this.listaReservas = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        this.listaReservas =
                bean.buscarReservaSalaTodos(sala.getCodSala(),
                        format.format(this.fechaSeleccionada));
        buscarSegmentosMB();
        return "detalleReserva?faces-redirect=true";
    }

    /**
     * 
     * Mismo metodo que el anterior pero para usuario normal. Luego deberia
     * cambiarlo dependiendo del tipo usuario que esta ingresando.
     * 
     * @return direccion.
     */
    public String redireccionarBuscarNormal() {
        this.usuario = new Usuario();
        this.listaReservas = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        this.listaReservas =
                bean.buscarReservaSalaNormal(sala.getCodSala(), format
                        .format(this.fechaSeleccionada), usuarioMB
                        .getUsuarioIniciado().getUsername());
        buscarSegmentosMB();
        return "detalleReservaNormal?faces-redirect=true";
    }

    /**
     * 
     * Obtener la lista de reservas de una fecha con sala determinada.
     * 
     */
    public void obtenerListaReservas() {
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        this.listaReservas = null;
        this.listaReservas =
                bean.buscarReservaSalaTodos(sala.getCodSala(),
                        format.format(this.fechaSeleccionada));
    }

    /**
     * Metodo el cual dependiendo del usuario que inicio session redirecciona
     * a la pagina correspondiente para comenzar a realizar una reserva.
     * 
     */
    public String accionSala(Sala sala) {
        this.sala = sala;
        this.usuarioMB.desplegarUsuarios();
        return "revisarReservas?faces-redirect=true";
    }

    /**
     * 
     * Redireccionar a pagina Reservar cuando esta en accion un usuario
     * normal.
     * 
     * @param sala
     * @return
     */
    public String accionSalaNormal(Sala sala) {
        this.sala = sala;
        this.usuarioMB.desplegarUsuarios();
        return "revisarReservasNormal?faces-redirect=true";
    }

    public void buscarSegmentosMB() {
        this.segmentos = bean.buscarSegmentos();
    }

    /**
     * Agregar una recerva. Se obtiene los datos individualmente no como
     * objetos. Se hacen las validaciones de horario/fecha correspondientes y
     * se retorna una direccion.
     * 
     */
    public String agregarReservaNormal() {
        this.usuarioMB.setUsuario(usuarioMB.getUsuarioIniciado());
        return agregarReserva();
    }

    /**
     * Agregar una recerva. Se obtiene los datos individualmente no como
     * objetos. Se hacen las validaciones de horario/fecha correspondientes y
     * se retorna una direccion.
     * 
     */
    public String agregarReserva() {
        SimpleDateFormat formatoHora =
                new SimpleDateFormat("yyy-MM-dd HH:mm:ss.SS");
        try {
            Date date = new Date();
            this.reservaSala.setCod_sala(sala.getCodSala());
            this.reservaSala.setUsername(usuarioMB.getUsuario().getUsername());
            this.reservaSala.setSegmentoFinal(formatoHora
                    .parse(segmentoTermino));
            this.reservaSala.setSegmentoInicial(formatoHora
                    .parse(segmentoInicial));
            this.reservaSala.setEstado(true);
            this.reservaSala.setFechaInicio(fechaSeleccionada);
            if (formatoHora.parse(segmentoTermino).before(
                    formatoHora.parse(segmentoInicial))) {
                saveMessage("La fecha de termino debe ser mayor a la de inicio.");
                return "detalleReserva";
            }
            if (formatoHora.parse(segmentoTermino).equals(
                    formatoHora.parse(segmentoInicial))) {
                saveMessage("Datos iguales.");
                return "detalleReserva";
            }
            if (bean.buscarReservaSalaAgregado(this.reservaSala)) {
                saveMessage("Ya existe un bloque horario asignado para el seleccionado.");
            } else {
                bean.agregarReservaSalaBean(reservaSala);
                obtenerListaReservas();
            }
        } catch (ParseException e) {
            // Logger.
        }
        return segmentoInicial;
    }

    /**
     * 
     * MB comenzado a eliminar una reserva.
     * 
     * @param dato
     *            Datos de la reserva a borrar.
     */
    public void borrarReserva(ReservaSala dato) {
        try {
            bean.eliminarReservaSalaBean(dato);
            obtenerListaReservas();
        } catch (NoExisteReserva e) {
            // Logger
            saveMessage(e.getMessage());
        }
    }

    /**
     * Growl.
     * 
     * @param msg
     *            Se entrega el string de msg.
     */
    public static void saveMessage(String msg) {
        RequestContext.getCurrentInstance().update("miform");
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage("gfMessages", new FacesMessage(
                FacesMessage.SEVERITY_ERROR, "Alerta", "" + msg));
    }

    public Date getFechaSeleccionada() {
        return fechaSeleccionada;
    }

    public void setFechaSeleccionada(Date fechaSeleccionada) {
        this.fechaSeleccionada = fechaSeleccionada;
    }

    public Usuario getUsuario() {
        return usuario;
    }

    public void setUsuario(Usuario usuario) {
        this.usuario = usuario;
    }

    public SalaMB getSalaMB() {
        return salaMB;
    }

    public void setSalaMB(SalaMB salaMB) {
        this.salaMB = salaMB;
    }

    public ReservaSala getReservaSala() {
        return reservaSala;
    }

    public void setReservaSala(ReservaSala reservaSala) {
        this.reservaSala = reservaSala;
    }

    public UsuarioMB getUsuarioMB() {
        return usuarioMB;
    }

    public void setUsuarioMB(UsuarioMB usuarioMB) {
        this.usuarioMB = usuarioMB;
    }

    public Sala getSala() {
        return sala;
    }

    public void setSala(Sala sala) {
        this.sala = sala;
    }

    public List<Segmentos> getSegmentos() {
        return segmentos;
    }

    public void setSegmentos(List<Segmentos> segmentos) {
        this.segmentos = segmentos;
    }

    public List<ReservaSala> getListaReservas() {
        return listaReservas;
    }

    public void setListaReservas(List<ReservaSala> listaReservas) {
        this.listaReservas = listaReservas;
    }

    public String getAux1() {
        return segmentoInicial;
    }

    public void setAux1(String aux1) {
        this.segmentoInicial = aux1;
    }

    public String getAux2() {
        return segmentoTermino;
    }

    public void setAux2(String aux2) {
        this.segmentoTermino = aux2;
    }
}
